package com.ddmmo.exhibition.localBOSS.videoStream.service.impl;

import com.ddmmo.exhibition.localBOSS.videoStream.service.VideoStreamService;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * <p>
 * 在线播放视频流 - Impl
 * </p>
 *
 * @author JiangYiji
 * @since 2024/10/30
 */
@Service
public class VideoStreamServiceImpl implements VideoStreamService {

    /**
     * 在线播放视频流
     */
    @Override
    public void openVideoForPath(String filePath, HttpServletResponse response, HttpServletRequest request) throws IOException {

        File videoFile = new File(filePath);

        if (!videoFile.exists()) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        // 设置视频流
        response.setContentType("video/mp4");
        long fileLength = videoFile.length();
        long start = 0;
        long end = fileLength - 1;

        // 处理范围请求
        String range = request.getHeader("Range");
        if (range != null) {
            String[] ranges = range.replaceAll("bytes=", "").split("-");
            start = Long.parseLong(ranges[0]);
            if (ranges.length > 1) {
                end = Long.parseLong(ranges[1]);
            }

            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
            response.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength);
        } else {
            response.setHeader("Accept-Ranges", "bytes");
        }

        response.setContentLengthLong(end - start + 1);

        try (FileInputStream inputStream = new FileInputStream(videoFile);
             BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream())) {

            inputStream.skip(start);
            byte[] buffer = new byte[4096];
            long bytesToWrite = end - start + 1;
            int bytesRead;

            while (bytesToWrite > 0 && (bytesRead = inputStream.read(buffer, 0, (int) Math.min(buffer.length, bytesToWrite))) != -1) {
                outputStream.write(buffer, 0, bytesRead);
                bytesToWrite -= bytesRead;
            }
            outputStream.flush();
        } catch (IOException e) {
            if (!response.isCommitted()) {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "读取视频错误");
            }
        }
    }

}
